/*
 * PSP Software Development Kit - http://www.pspdev.org
 * -----------------------------------------------------------------------
 * Licensed under the BSD license, see LICENSE in PSPSDK root for details.
 *
 * main.c - Simple elf based network example.
 *
 * Copyright (c) 2005 James F <tyranid@gmail.com>
 * Some small parts (c) 2005 PSPPet
 *
 * $Id: main.c 1887 2006-05-01 03:54:06Z jim $
 * $HeadURL: svn://svn.ps2dev.org/psp/trunk/pspsdk/src/samples/net/simple/main.c $
 */
#include <pspkernel.h>
#include <pspdebug.h>
#include <pspsdk.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pspnet.h>
#include <pspnet_inet.h>
#include <pspnet_apctl.h>
#include <pspnet_resolver.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/select.h>
#include <errno.h>
#include <pspctrl.h>

#include "libmpdclient.h"
#include "menuPlaylist.h"
#include "menuFiles.h"

#define printf pspDebugScreenPrintf

#define MODULE_NAME "mpdclient"
#define true 1

PSP_MODULE_INFO(MODULE_NAME, 0, 1, 0);
PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER);

PSP_HEAP_SIZE_MAX ();

/* Exit callback */
int exit_callback(int arg1, int arg2, void *common) {
	sceKernelExitGame();
	return 0;
}

/* Callback thread */
int CallbackThread(SceSize args, void *argp) {
	int cbid;

	cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL);
	sceKernelRegisterExitCallback(cbid);
	sceKernelSleepThreadCB();

	return 0;
}

/* Sets up the callback thread and returns its thread id */
int SetupCallbacks(void) {
	int thid = 0;

	thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0,
			PSP_THREAD_ATTR_USER, 0);
	if (thid >= 0) {
		sceKernelStartThread(thid, 0, 0);
	}

	return thid;
}

/* Connect to an access point */

/*int connect_to_apctl(int config) {
	int err;
	int stateLast = -1;

	// Connect using the first profile
	err = sceNetApctlConnect(config);
	if (err != 0) {
		printf(MODULE_NAME ": sceNetApctlConnect returns %08X\n", err);
		return 0;
	}

	printf(MODULE_NAME ": Connecting...\n");
	while (1) {
		int state;
		err = sceNetApctlGetState(&state);
		if (err != 0) {
			printf(MODULE_NAME ": sceNetApctlGetState returns $%x\n", err);
			break;
		}
		if (state > stateLast) {
			printf("  connection state %d of 4\n", state);
			stateLast = state;
		}
		if (state == 4)
			break; // connected with static IP

		// wait a little before polling again
		sceKernelDelayThread(50 * 1000); // 50ms
	}
	printf(MODULE_NAME ": Connected!\n");

	if (err != 0) {
		return 0;
	}

	return 1;
}*/

int connect_to_apctl(int config) {
   int err;
   int state;
   int stateLast = -1;
   char stateinfo[25];
   char st_text[50];

   if ((err = sceNetApctlConnect(config)) < 0)
   {
      printf("sceNetApctlConnect returns %x.", err);
      goto error_connecting;
   }

   while (1)
   {
      if (sceWlanGetSwitchState() != 1)
      {
         printf( "WLAN switch is turned off.");
         err = -1;
         goto error_connecting;
      }

      if ((err = sceNetApctlGetState(&state)) < 0)
      {
         printf("sceNetApctlGetState returns %x.", err);
         goto error_connecting;
      }

      if (state != stateLast)
      {
         switch (state)
         {
            case PSP_NET_APCTL_STATE_DISCONNECTED:
               strcpy(stateinfo, "Disconnected");
               break;
            case PSP_NET_APCTL_STATE_SCANNING:
               strcpy(stateinfo, "Scanning");
               break;
            case PSP_NET_APCTL_STATE_JOINING:
               strcpy(stateinfo, "Joining");
               break;
            case PSP_NET_APCTL_STATE_GETTING_IP:
               strcpy(stateinfo, "Obtaining IP address");
               break;
            case PSP_NET_APCTL_STATE_GOT_IP:
               strcpy(stateinfo, "IP address obtained");
               break;
            case PSP_NET_APCTL_STATE_EAP_AUTH:
               strcpy(stateinfo, "EAP Authenticating");
               break;
            case PSP_NET_APCTL_STATE_KEY_EXCHANGE:
               strcpy(stateinfo, "Exchanging key information");
               break;
         }

         printf("Connection state %d: %s.\n", state, stateinfo);
         //print st_text to show connection state
         stateLast = state;
      }

      if (state == 4) goto connected;

      sceKernelDelayThread(50 * 1000);
   }

error_connecting:
   //print st_text to show error
connected:
   return (err < 0)?0:1;
}

int net_thread(SceSize args, void *argp) {
	int err;
	int current = 0;
	int menus = 2;
	int released = 1;
	mpd_Status * status;
	mpd_Connection * con;
	SceCtrlData pad;
	SceCtrlLatch latch;

	menu *menu[2];
	do {
		if ((err = pspSdkInetInit())) {
			printf(
					MODULE_NAME ": Error, could not initialise the network %08X\n",
					err);
			break;
		}

		if (connect_to_apctl(1)) {
			//connected, get my IPADDR and run test
			char szMyIPAddr[32];
			if (sceNetApctlGetInfo(8, szMyIPAddr) != 0)
				strcpy(szMyIPAddr, "unknown IP address");

			con = mpd_newConnection("192.168.1.130", 6600, 1000);
			if (con) {
				//printf("Conectado al servidor MPD\n");
				//printf("Creado menu 0");
				menu[0] = createPlaylistMenu();
				menu[0]->init(menu[0]->state, con);
				menu[0]->aboutToShow(menu[0]->state, con);
				//printf("Creado menu 1");
				menu[1] = createFilesMenu();
				menu[1]->init(menu[1]->state,con);

				while (1) {
					sceCtrlReadBufferPositive(&pad, 1);
					sceCtrlReadLatch(&latch);

					if (latch.uiRelease)
						released = 1;

					if (released) {
						released = 0;
						if (pad.Buttons & PSP_CTRL_RTRIGGER) {
							menu[current]->handleRT(menu[current]->state, con);
						}
						if (pad.Buttons & PSP_CTRL_LTRIGGER) {
							menu[current]->handleLT(menu[current]->state, con);
						}
						if (pad.Buttons & PSP_CTRL_UP) {
							menu[current]->handleUp(menu[current]->state, con);
							released = 1;
						}
						if (pad.Buttons & PSP_CTRL_DOWN) {
							menu[current]->handleDown(menu[current]->state, con);
							released = 1;
						}
						if (pad.Buttons & PSP_CTRL_CIRCLE) {
							menu[current]->handleC(menu[current]->state, con);
						}
						if (pad.Buttons & PSP_CTRL_CROSS) {
							menu[current]->handleX(menu[current]->state, con);
						}
						if (pad.Buttons & PSP_CTRL_SQUARE) {
							menu[current]->handleS(menu[current]->state, con);
						}
						if (pad.Buttons & PSP_CTRL_TRIANGLE) {
							menu[current]->handleT(menu[current]->state, con);
						}
						if (pad.Buttons & PSP_CTRL_LEFT) {
							if (current != 0) {
								menu[current]->aboutToHide(
										menu[current]->state, con);
								current--;
								menu[current]->aboutToShow(
										menu[current]->state, con);

							}
						}
						if (pad.Buttons & PSP_CTRL_RIGHT) {
							if (current != menus - 1) {
								menu[current]->aboutToHide(
										menu[current]->state, con);
								current++;
								menu[current]->aboutToShow(
										menu[current]->state, con);

							}
						}
						if (pad.Buttons & PSP_CTRL_START) {
							mpd_sendStatusCommand(con);
							mpd_Status * status = mpd_getStatus(con);
							mpd_finishCommand(con);
							if (status) {
								if (status->state == MPD_STATUS_STATE_PLAY) {
									mpd_sendPauseCommand(con, 1);
									mpd_finishCommand(con);
								} else if (status->state
										== MPD_STATUS_STATE_PAUSE) {
									mpd_sendPauseCommand(con, 0);
									mpd_finishCommand(con);
								} else if (status->state
										== MPD_STATUS_STATE_STOP) {
									mpd_sendPlayCommand(con, 0);
									mpd_finishCommand(con);
								}
								mpd_freeStatus(status);
							}
						}
						if (pad.Buttons & PSP_CTRL_SELECT) {
							mpd_sendStatusCommand(con);
							mpd_Status * status = mpd_getStatus(con);
							mpd_finishCommand(con);
							if (status) {
								int random = status->random;
								mpd_freeStatus(status);
								mpd_sendRandomCommand(con, !random);
								mpd_finishCommand(con);
							}
						}
					}

					/*if(con->error) {
					 printf("Error: %d, %s\n",con->errorCode, con->errorStr);
					 if(con->errorCode == 0) {
					 con = mpd_newConnection("192.168.1.130", 6600, 1000);
					 }
					 }*/

					sceKernelDelayThread(100 * 1000);

					//}

				}

			}
			printf("Adios!");
		}
	} while (0);

	return 0;
}

/* Simple thread */
int main(int argc, char **argv) {
	SceUID thid;

	SetupCallbacks();

	pspDebugScreenInit();

	/*if(pspSdkLoadInetModules() < 0)
	 {
	 printf("Error, could not load inet modules\n");
	 sceKernelSleepThread();
	 }*/
	sceUtilityLoadNetModule(1);
	sceUtilityLoadNetModule(3);

	/* Create a user thread to do the real work */
	thid = sceKernelCreateThread("net_thread", net_thread, 0x18, 0x10000,
			PSP_THREAD_ATTR_USER, NULL);
	if (thid < 0) {
		printf("Error, could not create thread\n");
		sceKernelSleepThread();
	}

	sceKernelStartThread(thid, 0, NULL);

	sceKernelExitDeleteThread(0);

	return 0;
}
